package com.beantools.util;

import com.beantools.entity.enums.DateFormatEnum;

import java.text.*;
import java.util.Date;
import java.util.Locale;

import static com.beantools.entity.enums.DateFormatEnum.ISO_DATETIME_FORMAT;
import static com.beantools.util.ObjectUtil.isNull;
import static com.beantools.util.StringUtil.isBlank;

/**
 * 处理时间的工具类
 *
 * @author baoya
 * @version 1.1.0
 * @since 1.0
 */

public class FastDateFormat {

    private FastDateFormat() {
    }

    public static SimpleDateFormat getInstance() {
        return new SimpleDateFormat();
    }

    public static SimpleDateFormat getInstance(String pattern) {
        return new SimpleDateFormat(pattern);
    }

    public static SimpleDateFormat getInstance(String pattern, Locale locale) {
        return new SimpleDateFormat(pattern, locale);
    }

    public static SimpleDateFormat getInstance(String pattern, DateFormatSymbols formatSymbols) {
        return new SimpleDateFormat(pattern, formatSymbols);
    }

    /**
     * 这是静态方法，通过{@code String}对象获取日期格式。
     *
     * @param date   日期
     * @param format 日期格式的字符串
     * @return 返回格式化后的字符串
     */
    public synchronized static String format(Date date, String format) {
        if (isNull(date)) {
            return null;
        }
        return getInstance(format).format(date);
    }

    /**
     * 这是格式化时间的方法。根据调用者传入的{@code format}的格式，实例化{@code FastDateFormat}的对象，
     * 并解析以秒长度的{code timeMillis}得到调用者所想要的时间字符串。
     *
     * @param format     格式化时间的枚举类{@link DateFormatEnum}
     * @param timeMillis 秒数的日期
     * @return 返回的是时间字符串
     */
    public synchronized static String fromat(Long timeMillis, String format) {
        if (isNull(timeMillis)) {
            throw new IllegalArgumentException("参数不能为空，否则，解析失败");
        }
        return getInstance(format).format(timeMillis);
    }

    /**
     * 这是静态方法，通过{@code DateFormatEnum}对象获取日期格式。如果不传，则使用默认的日期格式：
     * <pre>  ISO_DATETIME_FORMAT（"yyyy-MM-dd HH:mm:ss"）  </pre>
     * 通过format.value()拿到yyyy-MM-dd HH:mm:ss值
     *
     * @param date       日期
     * @param dateFormat {@code DateFormatEnum}实例化的对象
     * @return 返回格式化后的字符串
     */
    public synchronized static String formatByEnum(Date date, DateFormatEnum dateFormat) {
        if (isNull(date)) {
            return null;
        }
        return getInstance(isNull(dateFormat) ? ISO_DATETIME_FORMAT.value() : dateFormat.value()).format(date);
    }

    /**
     * 这是格式化时间的方法。根据调用者传入的{@code format}的格式，实例化{@code FastDateFormat}的对象，
     * 并解析以秒长度的{code timeMillis}得到调用者所想要的时间字符串。
     *
     * @param format     格式化时间的枚举类{@link DateFormatEnum}
     * @param timeMillis 秒数的日期
     * @return 返回的是时间字符串
     */
    public synchronized static String formatByEnum(long timeMillis, DateFormatEnum format) {
        if (isNull(timeMillis)) {
            throw new IllegalArgumentException("参数不能为空，否则，解析失败");
        }
        return getInstance(isNull(format) ? ISO_DATETIME_FORMAT.value() : format.value()).format(timeMillis);
    }

    /**
     * 这是解析时间的方法。根据调用传入的{@code format}的格式，
     * 实例化{@code FastDateFormat}的对象，并解析以秒长度的
     * {code timeMillis}得到调用者所想要的时间字符串。
     *
     * @param format 格式化时间的枚举类{@link DateFormatEnum}
     * @param source 时间字符串
     * @return 返回的是时间字符串
     */
    public synchronized static Date parse(DateFormatEnum format, String source) {
        format = isNull(format) ? ISO_DATETIME_FORMAT : format;
        return parse(format.value(), source);
    }

    /**
     * 这是解析时间的方法。根据调用传入的{@code format}的格式，
     * 实例化{@code FastDateFormat}的对象，并解析以秒长度的
     * {code timeMillis}得到调用者所想要的时间字符串。
     *
     * @param format 格式化时间的枚举类{@link DateFormatEnum}
     * @param source 时间字符串
     * @return 返回的是时间字符串
     */
    public synchronized static Date parse(String format, String source) {
        Date date = null;
        try {
            if (isBlank(source)) {
                return date;
            }
            date = getInstance(isBlank(format) ? ISO_DATETIME_FORMAT.value() : format).parse(source);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}
